package Main
{
	import flash.net.FileReference;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.events.CloseEvent;
	import mx.managers.PopUpManager;
	
	import singleton.ATLSingleton;
	import singleton.GUIController;
	import singleton.Session;

	/**
	 * Handles the actions on the Transformation state
	 * */
	public class TransformationHandler {
		private static var resultContent:ByteArray;
		private static var fileKeepers:FileReferenceHandlers;
		private static var resultKeeper:FileReference;
		private static var controller:GUIController = GUIController.getInstance();
		private static var atl:ATLSingleton = ATLSingleton.getInstance();
		public static var atlNames:ArrayCollection = new ArrayCollection();
		public static var allATLID:Dictionary = new Dictionary();
		
		private static var session:Session = Session.getInstance();
		
		public function TransformationHandler()	{}
		
		/**
		 * Receives the resulting content from the transformation
		 * */
		public static function receiveResultContent(bytes:ByteArray): void {
			
			//controller.getButton(GUIController.DOWNLOAD).setVisible(true);
			//controller.getButton(GUIController.VIEW).setVisible(true);
			//controller.getLabel(GUIController.DOWNLOAD).setVisible(true);
			controller.getLabel(GUIController.DOWNLOAD).text = "Size: " + Util.formatNumber((bytes.length/1024.0).toString()) + "KB";
			resultContent = bytes;
			//controller.getImage(GUIController.POINT).setVisible(true);
			//controller.getLabel(GUIController.INFO).setVisible(true);
			controller.getAction(GUIController.DOWNLOAD).play();
			
		}
		
		/**
		 * Resets the text on Source Model input
		 * */
		public static function resetModelField(): void {
			
			controller.getTextInput(GUIController.SRC_MODEL).text = "Source Model";
			controller.getImage(GUIController.WARN).setVisible(true);
			controller.getImage(GUIController.OK).setVisible(false);
		}
		
		/**
		 * Executes the transformation
		 * */
		public static function executeTransformation():void	{
			try {
				initFileHandlers();
				
				var rules:ArrayCollection = new ArrayCollection();
				
				var i:int;
				var ar:Array = controller.getDataGrid(GUIController.RULES).selectedItems;
				for (i = 0; i < controller.getDataGrid(GUIController.RULES).selectedItems.length; i++) {
					var item:Object = ar.pop();
					rules.addItem(item);
				}
				
				if (rules.length == 0) {
					Alert.show("You must select at least one transformation rule", "Error!");
					return;
				} else if (fileKeepers.browserSrcModel.data == null) {
					Alert.show("Select the required model for the ATL Transformation", "Error!");
					return;
				}
				atl.setATLRules(rules);
				controller.getProgressBar(GUIController.EXECUTE).setVisible(true);
				controller.getProgressBar(GUIController.EXECUTE).setProgress(90,100);
				
				var sourceModelName:String = controller.getTextInput(GUIController.SRC_MODEL_INPUT_NAME).text;
				controller.getWebService().uploadSourceModel(session.getId(), fileKeepers.browserSrcModel.data, sourceModelName);
				//controller.getWebService().executeTransformation(controller.getDataGrid(GUIController.ATL_FILE).selectedItem.toString(), files.browserSrcModel.data, rules);
				
			} catch (err:Error) {
				resetModelField();
				controller.getProgressBar(GUIController.EXECUTE).setVisible(false);
				Alert.show("Error while executing the transformation!");
			}
		}
		
		/**
		 * Handles the selection of a transformation
		 * */
		public static function selectTransformation():void {
			if (controller.getDataGrid(GUIController.ATL_FILE).selectedIndex != -1) {
				resetState();
				if (!controller.getDataGrid(GUIController.RULES).visible)
					controller.getAction(GUIController.EXECUTE).play();
				
				controller.getLabel(GUIController.ATL_FILE).text = controller.getDataGrid(GUIController.ATL_FILE).selectedItem.toString();
				atl.setCurrentId(allATLID[controller.getDataGrid(GUIController.ATL_FILE).selectedItem as String]);
				
				controller.getWebService().getATLInformation(session.getId(), atl.getCurrentId(), "#8");
				
				try {
					controller.getWebService().getATLInformation(session.getId(), atl.getCurrentId(), "#4");
					controller.getWebService().getATLInformation(session.getId(), atl.getCurrentId(), "#6");
					//container.sourceModelInput.setVisible(true);
				} catch (err:Error) {
					Alert.show(err.message);
					Alert.show("Couldn't retrieve transformation info");
				}
			}
		}
		
		/**
		 * Selects all rules from the rules grid
		 * */
		public static function selectAllRules():void {
			
			var i:int = 0;
			var indices:Array = new Array();
			for (i; i < ArrayCollection(controller.getDataGrid(GUIController.RULES).dataProvider).length; i++) {
				indices.push(i);
			}
			controller.getDataGrid(GUIController.RULES).selectedIndices = indices;
			controller.getDataGrid(GUIController.RULES).validateNow();
			getRuleDependencies();
			
		}
		
		/**
		 * Begins the selecting of the source model
		 * */
		public static function selectSourceModel():void	{
				initFileHandlers();
				fileKeepers.browserSrcModel.browse();
		}
		
		/**
		 * Begins the download for the resulting content from the transformation
		 * */
		public static function downloadResultContent():void	{
			try {
				if (resultKeeper == null) {
					resultKeeper = new FileReference();
				}
				resultKeeper.save(resultContent, controller.getLabel(GUIController.ATL_FILE).text.split(".")[0] + ".xmi");
				
				
				controller.getButton(GUIController.DOWNLOAD).setFocus();
				
				
			} catch (err:Error) {
				Alert.show("Error while saving the file!");
			}
		}
		
		/**
		 * Warns the user about the completion of the transformation
		 * */
		public static function transformationComplete(): void {
			Alert.show("Transformation finished! Would you like to view the resulting file now?", "Success!", (Alert.YES | Alert.NO), null, viewXMLManager);
			controller.getProgressBar(GUIController.EXECUTE).setVisible(false);
		}
		
		//Shows the resulting content from the transformation
		private static function viewXMLManager(event:CloseEvent): void {
			if (event.detail == Alert.YES) {
				showResultContent();
			}
		}
		
		
		public static function showResultContent():void {
			controller.showPopUp(resultContent);
		}
		
		//Initiates all FileReference objects
		private static function initFileHandlers(): void {
			if (fileKeepers == null) {
				fileKeepers = FileReferenceHandlers.getInstance();
			}
		}
		
		/**
		 * Initiates this state
		 * */
		public static function initState():void	{
			
			controller.changeState(GUIController.EXECUTE);
			controller.getWebService().getAllATLTransformations(session.getId());
		
		}
		
		/**
		 * Selects a transformation by name
		 * */
		public static function selectTransformationByName(name:String):Boolean {
			
			if (name == null || name == "" || name == "ATL Transformation") {
				return false
			}
			
			var found:Boolean = controller.getDataGrid(GUIController.ATL_FILE).findString(name);
			
			selectTransformation();
			return found;
			
		}
		
		public static function showRuleDependencies():void {
			//todo
		}
		
		/**
		 * Requests the rule dependencies from each rule
		 * */
		public static function getRuleDependencies():void {
			var ar:Array = controller.getDataGrid(GUIController.RULES).selectedItems;
			var i:int;
			for (i = 0; i < controller.getDataGrid(GUIController.RULES).selectedItems.length; i++) {
				var item:Object = ar.pop();
				controller.getWebService().getATLRuleDependencies(session.getId(), atl.getCurrentId(), item as String);
			}
			
		}
		
		
		/**
		 * Returns to the main state
		 * */
		public static function backToMain(): void {
			if (controller.getDataGrid(GUIController.ATL_FILE).selectedIndex != -1) {
				controller.getAction(GUIController.EXECUTE).play(null, true);
				
			}
			controller.getAction(GUIController.DOWNLOAD).play(null, true);
			resetState();
			controller.getDataGrid(GUIController.RULES).setVisible(false);
			
			controller.changeState("Something");
		}
		
		//resets this state
		private static function resetState(): void {
			resultKeeper = new FileReference();
			controller.getTextInput(GUIController.SRC_MODEL).text = "Model";
			controller.getTextInput(GUIController.RULES).text = "";
			controller.getButton(GUIController.DOWNLOAD).setVisible(false);
			controller.getButton(GUIController.VIEW).setVisible(false);
			controller.getLabel(GUIController.DOWNLOAD).text = "";
			toggleExecutionButton(true);
			controller.getImage(GUIController.WARN).setVisible(true);
			controller.getImage(GUIController.OK).setVisible(false);
			controller.getImage(GUIController.POINT).setVisible(false);
			controller.getLabel(GUIController.INFO).setVisible(false);
			
		}
		
		/**
		 * Toggles the execution button so it can('t) be clicked
		 * */
		public static function toggleExecutionButton(locked:Boolean):void {
			if (locked) {
				controller.getTextInput(GUIController.SRC_MODEL).setStyle("chromeColor", 0xe1e1e1);
				controller.getTextInput(GUIController.SRC_MODEL).setStyle("color", 0x808080);
				controller.getButton(GUIController.EXECUTE).setStyle("chromeColor", 0xafafaf);
				controller.getButton(GUIController.EXECUTE).setStyle("color", 0xc4c4c4);
				controller.getButton(GUIController.EXECUTE).mouseEnabled = false;
			} else {
				controller.getTextInput(GUIController.SRC_MODEL).setStyle("chromeColor", 0xe1e1e1);
				controller.getTextInput(GUIController.SRC_MODEL).setStyle("color", 0x000000);
				controller.getButton(GUIController.EXECUTE).setStyle("chromeColor", 0xe3dddd);
				controller.getButton(GUIController.EXECUTE).setStyle("color", 0x000000);
				controller.getButton(GUIController.EXECUTE).mouseEnabled = true;
			}
		}
	
		public static function setDataProviderForDataGrid(type:String, provider:ArrayCollection):void {
			controller.getDataGrid(type).dataProvider = provider;
			controller.getDataGrid(type).validateNow();
		}
		
		public static function changeModelLabel(type:String, name:String):void {
			controller.getLabel(type).text = name;
		}
	}
}